<?php

namespace W3;

/**
 * 多语言管理类
 *
 * @author edikud
 * @date 2022/10/22
 * @copyright Copyright (c) 2022 W3 (http://www.mcooo.com)
 * @license GNU General Public License 2.0
 */
class Lang
{

    /**
     * 单例句柄
     *
     * @access protected
     * @var Lang
     */
    protected static $instance;
	
    /**
     * 单例实例
     *
     * @return Lang
     */
    public static function instance(): Lang
    {
        if (null === self::$instance) {
            self::$instance = new self();
        }

        return self::$instance;
    }

    /**
     * 创建新实例
     *
     * @access public
     * @return Lang
     */
    public static function make(): Lang
    {
        return new static();
    }
	
    /**
     * 多语言信息
     * @var array
     */
    private $data = [];

    /**
     * 当前语言
     * @var string
     */
    private $default = 'zh-cn';

    /**
     * 设置/获取当前语言
     * @access public
     * @return string
     */
    public function default($default = NULL): string
    {
		if(NULL === $default){
			return $this->default;
		}
        $this->default = $default;
    }

    /**
     * 判断是否存在语言定义(不区分大小写)
     * @access public
     * @param string|null $name  语言变量
     * @param string      $lang 语言作用域
     * @return bool
     */
    public function exists(string $name, string $lang = ''): bool
    {
        $lang = $lang ?: $this->default;

        return isset($this->data[$lang][$name]);
    }

    /**
     * 加载语言定义(不区分大小写)
     * @access public
     * @param array $vars  语言
     * @param string $lang 语言作用域
     * @return array
     */
    public function set(array $vars, $lang = '')
    {
        $lang = $lang ?: $this->default;
        if (!isset($this->data[$lang])) {
            $this->data[$lang] = [];
        }

        if (!empty($lang)) {
            $this->data[$lang] = $vars + $this->data[$lang];
        }
    }
	
    /**
     * 获取语言定义(不区分大小写)
     * @access public
     * @param string|null $name  语言变量
     * @param array       $vars  变量替换
     * @param string      $lang 语言作用域
     * @return mixed
     */
    public function get(string $name, array $vars = [], string $lang = '')
    {
        $lang = $lang ?: $this->default;

        $value = $this->data[$lang][$name] ?? $name;

        // 变量解析
        if (!empty($vars) && is_array($vars)) {
            /**
             * Notes:
             * 为了检测的方便，数字索引的判断仅仅是参数数组的第一个元素的key为数字0
             * 数字索引采用的是系统的 sprintf 函数替换，用法请参考 sprintf 函数
             */
            if (key($vars) === 0) {
                // 数字索引解析
                $value = sprintf($value, ...$vars);
            } else {
                // 关联索引解析
                $replace = array_keys($vars);
                foreach ($replace as &$v) 
				{
                    $v = "{:{$v}}";
                }
                $value = str_replace($replace, $vars, $value);
            }
        }

        return $value;
    }

    /**
     * 返回所有定义
     * @access public
     * @return array
     */
    public function export(): array
    {
        return $this->data;
    }
}
